package com.cloudfun.campusshare.controller;

import com.cloudfun.campusshare.common.constant.AuthType;
import com.cloudfun.campusshare.common.constant.Code;
import com.cloudfun.campusshare.common.constant.RoleType;
import com.cloudfun.campusshare.common.exception.BusinessException;
import com.cloudfun.campusshare.common.model.dto.BatchOperateDTO;
import com.cloudfun.campusshare.common.model.dto.LoanDTO;
import com.cloudfun.campusshare.common.model.dto.LoanIssueDTO;
import com.cloudfun.campusshare.common.model.dto.LoanQueryDTO;
import com.cloudfun.campusshare.common.model.vo.*;
import com.cloudfun.campusshare.common.response.BaseResult;
import com.cloudfun.campusshare.common.response.BaseResultFactory;
import com.cloudfun.campusshare.common.response.PageResult;
import com.cloudfun.campusshare.common.security.AuthRequired;
import com.cloudfun.campusshare.common.security.AuthenticationHolder;
import com.cloudfun.campusshare.entity.UserEntity;
import com.cloudfun.campusshare.repo.UserEntityRepo;
import com.cloudfun.campusshare.service.LoanService;
import com.cloudfun.campusshare.util.ExcelUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;

/**
 * Created by Huqin on 2020/3/4
 */
@Slf4j
@RestController
@RequestMapping("/v1/loan")
@Api(value = "融资贷款模块")
@AuthRequired
public class LoanController {

    @Autowired
    private LoanService loanService;

    @Autowired
    private UserEntityRepo userEntityRepo;

    @ApiOperation(value = "创建草稿")
    @PostMapping("/create-draft")
    @AuthRequired(role = RoleType.OPERATIONAL_MERCHANT, auth = AuthType.ORG)
    public BaseResult<?> createDraft(@ApiParam(value = "LoanDTO", required = true) @Valid @RequestBody LoanDTO loanDTO) {
        return loanService.createDraft(loanDTO);
    }

    @ApiOperation(value = "获取草稿")
    @GetMapping("/draft")
    public BaseResult<LoanDraftVO> draft(@ApiParam(value = "融资贷款id", required = true) @RequestParam String loanId) {
        return BaseResultFactory.produceResult(Code.SUCCESS, loanService.getDraft(loanId));
    }


    @ApiOperation(value = "创建融资贷款申请")
    @PostMapping("/apply")
    @AuthRequired(role = RoleType.OPERATIONAL_MERCHANT, auth = AuthType.ORG)
    public BaseResult<?> apply(@ApiParam(value = "LoanDTO", required = true) @RequestBody LoanDTO loanDTO) {
        return loanService.apply(loanDTO);
    }

    @ApiOperation(value = "详情")
    @GetMapping("/detail")
    @AuthRequired(role = RoleType.OPERATIONAL_MERCHANT)
    public BaseResult<LoanVO> detail(@ApiParam(value = "融资贷款id", required = true) @RequestParam String loanId) {
        return BaseResultFactory.produceResult(Code.SUCCESS, loanService.detail(loanId));
    }

    @ApiOperation(value = "融资贷款申请详情")
    @GetMapping("/apply/detail")
    @AuthRequired(role = {RoleType.FINANCIAL_INSTITUTIONS, RoleType.ADMIN})
    public BaseResult<LoanApplyDetailVO> applyDetail(@ApiParam(value = "融资贷款id", required = true) @RequestParam String loanId) {
        return BaseResultFactory.produceResult(Code.SUCCESS, loanService.applyDetail(loanId));
    }

    @DeleteMapping
    @ApiOperation("删除融资贷款")
    @AuthRequired(role = RoleType.OPERATIONAL_MERCHANT, auth = AuthType.ORG)
    BaseResult<?> delete(@ApiParam(value = "融资贷款id", required = true) @RequestParam String loanId) {
        loanService.delete(loanId);
        return BaseResultFactory.produceEmptyResult(Code.SUCCESS);
    }

    @GetMapping("/list")
    @ApiOperation("融资贷款分页列表")
    @AuthRequired(role = {RoleType.OPERATIONAL_MERCHANT, RoleType.FINANCIAL_INSTITUTIONS, RoleType.ADMIN})
    BaseResult<PageResult<LoanListVO>> search(Pageable pageable, @ApiParam(value = "LoanQueryDTO", required = true) LoanQueryDTO loanQueryDTO) {
        return BaseResultFactory.produceResult(Code.SUCCESS, loanService.search(loanQueryDTO, pageable));
    }

    @GetMapping("/export/fi")
    @ApiOperation("金融机构导出融资贷款")
    @AuthRequired(role = RoleType.FINANCIAL_INSTITUTIONS)
    void fiExport(HttpServletResponse response, @ApiParam(value = "LoanQueryDTO", required = true) LoanQueryDTO loanQueryDTO) throws Exception {
        long start = System.currentTimeMillis();
        String userId = StringUtils.isNotBlank(loanQueryDTO.getBorrowerId()) ? loanQueryDTO.getBorrowerId() : AuthenticationHolder.getUserId();
        List<LoanFiExportVO> exportVOList = loanService.fiExport(loanQueryDTO);
        log.debug("金融机构导出{}个融资贷款信息记录耗时：{}ms", exportVOList.size(), (System.currentTimeMillis() - start));
        UserEntity userEntity = userEntityRepo.findById(userId).orElse(null);
        ExcelUtils.exportExcel(exportVOList, null, "融资贷款信息", LoanFiExportVO.class, userEntity.getEnterpriseName() + "-FinancialLoans", response);
    }

    @GetMapping("/export/borrower-admin")
    @ApiOperation("管理员导出运营型商家融资贷款")
    @AuthRequired(role = RoleType.ADMIN)
    void adminExportBorrowerLoan(HttpServletResponse response, @ApiParam(value = "LoanQueryDTO", required = true) LoanQueryDTO loanQueryDTO) throws Exception {
        String borrowerId = loanQueryDTO.getBorrowerId();
        if (StringUtils.isBlank(borrowerId)) {
            throw new BusinessException(Code.PARAMETER_ERROR);
        }
        long start = System.currentTimeMillis();
        List<BorrowerLoanAdminExportVO> exportVOList = loanService.adminExportBorrowerLoan(loanQueryDTO);
        log.debug("管理员导出{}个运营型商家融资贷款信息记录耗时：{}ms", exportVOList.size(), (System.currentTimeMillis() - start));
        UserEntity userEntity = userEntityRepo.findById(borrowerId).orElse(null);
        ExcelUtils.exportExcel(exportVOList, null, "融资贷款信息", BorrowerLoanAdminExportVO.class, userEntity.getEnterpriseName() + "-FinancialLoans", response);
    }

    @GetMapping("/export/lender-admin")
    @ApiOperation("管理员导出金融机构融资贷款")
    @AuthRequired(role = RoleType.ADMIN)
    void adminExportLenderLoan(HttpServletResponse response, @ApiParam(value = "LoanQueryDTO", required = true) LoanQueryDTO loanQueryDTO) throws Exception {
        String lenderId = loanQueryDTO.getLenderId();
        if (StringUtils.isBlank(lenderId)) {
            throw new BusinessException(Code.PARAMETER_ERROR);
        }
        long start = System.currentTimeMillis();
        List<LenderLoanAdminExportVO> exportVOList = loanService.adminExportLenderLoan(loanQueryDTO);
        log.debug("管理员导出{}个金融机构融资贷款信息记录耗时：{}ms", exportVOList.size(), (System.currentTimeMillis() - start));
        UserEntity userEntity = userEntityRepo.findById(lenderId).orElse(null);
        ExcelUtils.exportExcel(exportVOList, null, "融资贷款信息", LenderLoanAdminExportVO.class, userEntity.getEnterpriseName() + "-FinancialLoans", response);
    }

    @GetMapping("/export/admin")
    @ApiOperation("管理员导出融资贷款")
    @AuthRequired(role = RoleType.ADMIN)
    BaseResult<?> adminExport(HttpServletResponse response, @ApiParam(value = "BatchOperateDTO", required = true) BatchOperateDTO<String> batchOperateDTO) throws Exception {
        if (CollectionUtils.isEmpty(batchOperateDTO.getIds()) && StringUtils.isBlank(batchOperateDTO.getSearchData()) && !BooleanUtils.isTrue(batchOperateDTO.getAll())) {
            return BaseResultFactory.produceEmptyResult(Code.PARAMETER_ERROR, "参数错误");
        }
        long start = System.currentTimeMillis();
        List<LoanAdminExportVO> exportVOList;
        if (!CollectionUtils.isEmpty(batchOperateDTO.getIds())) {
            exportVOList = loanService.adminExport(batchOperateDTO.getIds(), null);
        } else if (null != batchOperateDTO.getSearchData()) {
            exportVOList = loanService.adminExport(null, batchOperateDTO.getSearchData());
        } else {
            exportVOList = loanService.adminExport(null, null);
        }
        log.debug("管理员导出{}个融资贷款信息记录耗时：{}ms", exportVOList.size(), (System.currentTimeMillis() - start));
        ExcelUtils.exportExcel(exportVOList, null, "融资贷款信息", LoanAdminExportVO.class, "FinancialLoans", response);
        return BaseResultFactory.produceEmptyResult(Code.SUCCESS);
    }

    @PostMapping("/issue")
    @ApiOperation("金融机构放款")
    @AuthRequired(role = RoleType.FINANCIAL_INSTITUTIONS, auth = AuthType.ORG)
    BaseResult<?> issueLoan(@ApiParam(value = "LoanIssueDTO", required = true) @RequestBody LoanIssueDTO loanIssueDTO) {
        loanService.issueLoan(loanIssueDTO);
        return BaseResultFactory.produceEmptyResult(Code.SUCCESS);
    }

    @PostMapping("/confirm")
    @ApiOperation("运营商确认收款")
    @AuthRequired(role = RoleType.OPERATIONAL_MERCHANT, auth = AuthType.ORG)
    BaseResult<?> confirm(@ApiParam(value = "融资贷款id", required = true) @RequestParam String loanId) {
        loanService.confirm(loanId);
        return BaseResultFactory.produceEmptyResult(Code.SUCCESS);
    }
}
